package models

import (
	"errors"
	"fmt"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cast"
	"gorm.io/gorm"
	"strconv"
)

type User struct {
	Model
	Password string `json:"password" gorm:"comment:'密码'"`
	NickName string `json:"nick_name" gorm:"comment:'昵称'"`
	RealName string `json:"real_name" gorm:"comment:'真实姓名'"`
	Mobile   string `json:"mobile" gorm:"unique_index,comment:'手机号码'"`
	Sex      int    `json:"sex" gorm:"default:0;comment:'性别: 0=男 1=女'"`
	Avatar   string `json:"avatar" gorm:"comment:'头像名称'"`
	Remark   string `json:"remark" gorm:"comment:'备注'"`
	Ip       string `json:"ip,omitempty" gorm:"ip地址"`
}

// ExistUserByID 通过id判断是否存在
func ExistUserByID(id int) (bool, error) {
	var user User
	err := db.Select("id").Where("id = ?", id).First(&user).Error
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		return false, err
	}

	if user.ID > 0 {
		return true, nil
	}

	return false, nil
}

// ExistUserByMobile 通过mobile判断是否存在
func ExistUserByMobile(mobile string) (bool, error) {
	var user User
	err := db.Select("id").Where("mobile = ?", mobile).First(&user).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return false, err
	}

	if user.ID > 0 {
		return true, nil
	}

	return false, nil
}

// ExistUserByName 通过昵称判断是否存在
func ExistUserByName(nick string) (bool, error) {
	var user User
	err := db.Select("id").Where("nick_name = ?", nick).First(&user).Error
	if err != nil && err != gorm.ErrRecordNotFound {
		return false, err
	}

	if user.ID > 0 {
		return true, nil
	}

	return false, nil
}

// UserInfoByID 通过id获取详情
func UserInfoByID(id interface{}) (map[string]string, error) {
	user := new(User)

	err := db.Model(&User{}).Where("id = ?", id).Scan(&user).Error
	if (err != nil && err != gorm.ErrRecordNotFound) || user.ID == 0 {
		logrus.Error(fmt.Sprintf("UserInfoByID id:%s err:%s", id, err.Error()))
		return nil, errors.New("此用户不存在")
	}

	return map[string]string{
		"id":        cast.ToString(user.ID),
		"nick_name": user.NickName,
		"real_name": user.RealName,
		"mobile":    user.Mobile,
		"sex":       strconv.Itoa(user.Sex),
		"avatar":    user.Avatar,
		"remark":    user.Remark,
		"ip":        user.Ip,
	}, nil
}

// UserLogin 通过手机号密码登录
func UserLogin(mobile string, password string) (map[string]string, error) {
	user := new(User)

	if cast.ToInt16(mobile) == 0 {
		return nil, errors.New("请输入手机号码")
	}

	if cast.ToInt16(password) == 0 {
		return nil, errors.New("请输入密码")
	}

	err := db.Model(&User{}).Where("mobile = ? AND password = ?", mobile, password).Scan(&user).Error
	if (err != nil && err != gorm.ErrRecordNotFound) || user.ID == 0 {
		logrus.Error(fmt.Sprintf("/api/v1/user/login mobile:%s password:%s err:%s", mobile, password, err.Error()))
		return nil, errors.New("账号或密码错误")
	}

	return map[string]string{
		"id":        cast.ToString(user.ID),
		"nick_name": user.NickName,
		"real_name": user.RealName,
		"mobile":    user.Mobile,
		"sex":       strconv.Itoa(user.Sex),
		"avatar":    user.Avatar,
		"remark":    user.Remark,
		//"ip":        user.Ip,
	}, nil
}

// EditUser 编辑用户资料
func EditUser(id int, data interface{}) error {
	if err := db.Model(&User{}).Where("id = ?", id).Updates(data).Error; err != nil {
		return err
	}
	return nil
}

// EditUserPassword 编辑用户密码
func EditUserPassword(id int, password string, nPwd string) error {
	user := new(User)
	err := db.Model(&User{}).Where("id = ? AND password = ?", id, password).Scan(&user).Error
	if (err != nil && err != gorm.ErrRecordNotFound) || user.ID == 0 {
		logrus.Error(fmt.Sprintf("/api/v1/user/editPassword 账号与密码不匹配 id:%d password:%s npwd:%s err:%s", id, password, nPwd, err.Error()))
		return errors.New("修改密码失败")
	}
	err = db.Model(&user).Update("password", nPwd).Error
	if err != nil {
		logrus.Error(fmt.Sprintf("/api/v1/user/editPassword 更新操作失败 id:%d password:%s npwd:%s err:%s", id, password, nPwd, err.Error()))
		return errors.New("修改密码失败")
	}
	return nil
}

// UserDelete 删除用户
func UserDelete() (bool, error) {
	if err := db.Unscoped().Where("deleted_on != ? ", 0).Delete(&User{}).Error; err != nil {
		return false, err
	}

	return true, nil
}

// UserAdd 添加用户
func UserAdd(data map[string]interface{}) (string, error) {
	user := User{
		Password: data["password"].(string),
		NickName: data["nick_name"].(string),
		RealName: data["real_name"].(string),
		Mobile:   data["mobile"].(string),
		Sex:      data["sex"].(int),
		Avatar:   data["avatar"].(string),
		Remark:   data["remark"].(string),
	}

	if err := db.Create(&user).Error; err != nil {
		return "", err
	}

	return cast.ToString(user.ID), nil
}
